<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { merge } from 'lodash-es'
import { useRoute } from 'vue-router'
import { contributionConfig } from '../../config'
import type { ICaseTableItem } from '../../type'
import { runCase, updateCase } from '@/api/cases'
import { barBaseOptions } from '@/components/ui/chart/src/barOptions'
import useStore from '@/stores'
import { useFetch } from '@/composables/useFetch'
import { isEmptyObject } from '@/utils'
import { useCaseResult } from '@/views/cases/components/useCaseResult'

const route = useRoute()
const { cases } = useStore()
const caseInfo = computed(() => cases.caseInfo)
const detailData = computed(() => caseInfo.value?.jsonArgs ? JSON.parse(caseInfo.value?.jsonArgs) : null)
const contributionFormRef = ref()
const barOptions = ref(barBaseOptions)
// const contributionOptions = ref<any[]>([])

const { loading: runLoading, execute: runCaseExecute } = useFetch((parmas: any = {}) => runCase(parmas))
const { execute: updateCaseExecute } = useFetch((parmas: ICaseTableItem) => updateCase(parmas))

// 获取结果
const { contributionResult, contributionLoading, onClickRefreshAllAction } = useCaseResult()
watch(() => contributionResult.value, () => {
  if (isEmptyObject(contributionResult.value)) {
    barOptions.value = barBaseOptions
    return
  }

  _setChartOption(contributionResult.value)
}, { deep: true })

// 共用一个按钮加载状态
watch(() => runLoading.value, (val: boolean) => {
  cases.setCaseRunLoading(val)
})

// 保存表单信息
watch([() => contributionFormRef.value?.model], () => {
  cases.initFormInfoSkip()
  const formInfo = Object.assign({}, cases.formInfo, { Contribution: { ...contributionFormRef.value.model, skip: false } })
  cases.saveFormInfo(formInfo)
}, { deep: true })

// 接口的表单字段有变化需要重新回填表单
watch(() => detailData.value?.Contribution, (nVal: any) => {
  if (nVal)
    initForm()
}, { deep: true })

onMounted(async () => {
  // console.log('onMounted', cases.clusterMax, cases.formInfo?.Cluster.n_clusters)
  // 根据clusterMax去限定下拉列表的最大值
  // await handleFormValidate(cases.clusterMax)
  await handleFormValidate()
  initForm()
})

onBeforeUnmount(() => {
  contributionResult.value = null as any
  barOptions.value = null as any
})

// 处理表单的特殊校验 添加validator
const contributionOptions = ref<any[]>([])
async function handleFormValidate() {
  async function validateLabel(_rule: any, value: number) {
    if (!value && value !== 0)
      return Promise.reject('Please enter the label again')

    if (value < 1)
      return Promise.reject(`The value of label must be greater than 1`)

    if (cases.clusterMax > 1 && value > cases.clusterMax)
      return Promise.reject(`The value of label must be less than ${cases.clusterMax}`)

    return Promise.resolve(true)
  }
  contributionOptions.value = contributionConfig.contributionFormOptions.map((item: any) => {
    if (item.prop === 'label1' || item.prop === 'label2')
      item.rules[0].validator = validateLabel
    return item
  })
}

// 处理表单的特殊校验 添加children

// async function handleFormValidate(cluster: number) {
//   // 根据第一步表单中的n_clusters字段确定当前表单的label字段的上限
//   watch(() => cluster, (nVal: number) => {
//     const children = Array.from({ length: nVal }, (_item, i) => ({
//       type: 'select-option',
//       value: i + 1,
//       label: i + 1,
//     }))

//     contributionOptions.value = contributionConfig.contributionFormOptions.map((item: any) => {
//       if (item.prop === 'label1' || item.prop === 'label2')
//         item.children = children
//       return item
//     })
//   }, { immediate: true })
// }

function initForm() {
  if (detailData.value && !isEmptyObject(detailData.value))
    contributionFormRef.value.model = detailData.value.Contribution
}

function onClickSubmitRun() {
  const validate = contributionFormRef.value.validate()

  validate().then(async () => {
    // 后端进行缓存全量参数
    await updateCaseExecute({ caseId: route.query.id, jsonArgs: JSON.stringify(cases.formInfo) })

    // 运行操作
    await runCaseExecute({ caseId: route.query.id })
  })
}

const rankValue = ref()
function getRankData(arr: number[], rank: number) {
  const sortedArr = arr.slice().sort((a, b) => a - b)
  const topList = sortedArr.slice(sortedArr.length - rank)
  const indices = []
  for (const num of topList)
    indices.push(arr.indexOf(num))

  return {
    topList,
    indices,
  }
}

function onClickRank() {
  _setChartOption(contributionResult.value)
}

function _setChartOption(resultData: any) {
  const { data, index } = resultData?.contribution
  const max = Math.ceil(Math.max(...data.flat()))
  const rankData = getRankData(data.flat(), rankValue.value || 1000)
  const rankIndex = []
  for (const idx of rankData.indices)
    rankIndex.push(index[idx])

  barOptions.value = merge(
    {},
    barBaseOptions,
    {
      grid: { left: '140px' },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow',
        },
      },
      visualMap: {
        type: 'piecewise', // 连续型
        min: 0,
        max,
        top: 'center', // 垂直居中
        right: 10, // 距离左边的距离
        dimension: 0,
        inRange: {
          color: [
            '#000094',
            '#0000fc',
            '#005cff',
            '#00c0ff',
            '#26ffda',
            '#8eff72',
            '#eeff12',
            '#ffac00',
            '#ff4800',
            '#e40000',
          ],
        },
      },
      xAxis: {
        name: 'Contribution',
        nameLocation: 'center',
        nameTextStyle: {
          lineHeight: 50,
        },
        type: 'value',
      },
      yAxis: {
        type: 'category',
        // data: index,
        data: rankIndex,
      },
      series: [
        {
          data: rankData.topList,
        },
      ],
    },
  )
}

defineExpose({ onClickSubmitRun, onClickRefreshAllAction })
</script>

<template>
  <div class="case-contribution-wrapper case-form-wrapper">
    <GpForm ref="contributionFormRef" layout="vertical" :options="contributionOptions" class="gp__grid-three" />
    <div class="chart-box">
      <a-card title="Contribution">
        <template #extra>
          <div class="row">
            <span>Rank: </span>
            <a-input-number
              v-model:value="rankValue"
              :min="1"
              :max="1000"
              size="small"
              style="width: 100px; margin: 0 10px"
            />
            <a-button type="primary" size="small" @click="onClickRank">
              confirm
            </a-button>
          </div>
        </template>
        <a-spin tip="loading..." :spinning="contributionLoading">
          <GpChart id="case1Bar" style="margin: 0 auto;" height="600px" :options="barOptions" />
          <span class="con-name">Variables</span>
        </a-spin>
      </a-card>
    </div>
  </div>
</template>

<style lang="less" scoped>
@import url('../../common.less');
.chart-box {
  position: relative;
  .con-name {
    position: absolute;
    top: 50%;
    transform: rotate(-90deg);
  }
}
</style>
